home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / quartz / quartz10.lha / src / presto / spinlock.h < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  3.6 KB  |  188 lines

  1. //
  2. // Spinlocks should be used when the caller expects to need to touch
  3. // a piece of data for only a very short time.  Interference on that
  4. // data will cause the later thread to spin (his processor does not
  5. // become available!)
  6. //
  7. //    USE WITH CAUTION
  8. //
  9. // Modification History:
  10. //
  11. // 28-Dec-1989  JEF
  12. // Add class HC_Spinlock (for sequent symmetry only).  This variation of
  13. // a spinlock works well when there is high contention for the lock.
  14. // After original by raj.
  15. //
  16.  
  17. //
  18. // If compiling presto kernel, or compiling with preemption 
  19. // included, then include code to make threads not preemptable
  20. // inside spinlock.  Else, omit for speed.
  21. //
  22.  
  23. //
  24. //  For better locking performance, spinlocks should be compiled inline.
  25. //  Note - this results in lots of warnings of the form:
  26. //    .... warning:  undeclared function S_LOCK() called
  27. //  These can be ignored - C++ can't find the functions because they are
  28. //  asm functions, which C++ doesn't know about.  The functions are pulled
  29. //  into the C++ C output via the +hasmdefs.h C++ flag prior to cc compilation.
  30. //
  31. #define DO_SPINLOCK_INLINE
  32.  
  33. #ifdef DO_SPINLOCK_INLINE
  34. #define SPINLOCK_INLINE     inline
  35. #else
  36. #define SPINLOCK_INLINE
  37. #endif
  38.  
  39. #ifdef sequent
  40. #include "parallel.h"
  41. #endif sequent
  42. #ifdef sun
  43. #include "parallel.h"
  44. #endif sun
  45.  
  46. #ifdef vax 
  47. typedef    int slock_t;
  48. #define L_UNLOCKED 0
  49.  
  50. #define S_LOCK s_lock
  51. #define S_UNLOCK s_unlock
  52.  
  53. //
  54. // For the vax, the underlying lock functions are in vax_lock.s and
  55. // spinlock.c.  The s_lock and s_unlock functions do not return a
  56. // meaningful result.
  57. //
  58. #endif vax
  59. #ifdef sun
  60. #define S_LOCK s_lock
  61. #endif sun
  62.  
  63. extern void s_init_lock(slock_t*);
  64. extern void s_lock(slock_t*);
  65. extern void s_unlock(slock_t*);
  66. extern int s_clock(slock_t*);
  67.  
  68. class Thread;
  69.  
  70. class Spinlock    : public Object  {    
  71.     slock_t        sl_lock;
  72. #ifdef PROFILE
  73.     int    sl_q;
  74. #endif
  75. public:
  76.     Spinlock(char *name = 0) 
  77.         {
  78.         s_init_lock(&sl_lock); 
  79. #ifdef PROFILE
  80.         sl_q = SLInit(name);
  81. #endif
  82.         }
  83.     SPINLOCK_INLINE ~Spinlock();
  84.  
  85.     //
  86.     // Acquire lock, spinning until it is free.
  87.     //
  88.     SPINLOCK_INLINE void lock();
  89.  
  90.     //
  91.     // Acquire lock and return true iff lock is free, else return
  92.     // false immediately without spinning.
  93.     //
  94.     int trylock()
  95.         { return  s_clock(&sl_lock); }
  96.  
  97.     //
  98.     // Old name for trylock().
  99.     //
  100.     int checklock()
  101.         { return  trylock(); }
  102.  
  103.     //
  104.     // Return true iff locked, else false.
  105.     //
  106.     int testlock()
  107.         { return  sl_lock; }
  108.  
  109.     //
  110.     // Release lock.
  111.     //
  112.     SPINLOCK_INLINE void unlock();
  113.     virtual void print(ostream& = cout);
  114. };
  115.      
  116.  
  117.  
  118. //
  119. //  High-contention spinlocks are only implemented on sequent symmetry.
  120. //
  121. #ifdef i386
  122. #include "parallel.h"
  123.  
  124. class Thread;
  125.  
  126. class HC_Spinlock : public Object  {    
  127.     hc_slock_t    sl_lock;
  128. #ifdef PROFILE
  129.     int    sl_q;
  130. #endif
  131. public:
  132.     HC_Spinlock(char *name = 0)
  133.         {
  134.         HC_S_INIT_LOCK(&sl_lock); 
  135. #ifdef PROFILE
  136.         sl_q = SLInit(name);
  137. #endif
  138.         }
  139.  
  140.     ~HC_Spinlock()
  141.     {
  142.         //
  143.         // We should abort if the lock is not free. (?) XXX
  144.         // For now just unlock it for backward compatibility.
  145.         //
  146.         if (testlock())
  147.             unlock();
  148. #ifdef PROFILE
  149.     SLDispose(sl_q);
  150. #endif
  151.     }
  152.  
  153.     //
  154.     // Acquire lock, spinning until it is free.
  155.     //
  156.     inline void lock();
  157.  
  158.     //
  159.     // Acquire lock and return true iff lock is free, else return
  160.     // false immediately without spinning.
  161.     //
  162.     int trylock()  {
  163.         cerr << "HC_Spinlock::trylock(): unimplemented\n"; 
  164.         /* XXX for now, always returns FALSE */
  165.         return (HC_S_CLOCK(&sl_lock));
  166.     }
  167.  
  168.     //
  169.     // Old name for trylock().
  170.     //
  171.     int checklock() 
  172.         { return (trylock()); }
  173.  
  174.     //
  175.     // Return true iff locked, else false.
  176.     //
  177.     int testlock()
  178.         { return  HC_S_IS_LOCKED(&sl_lock); }
  179.  
  180.     //
  181.     // Release lock.
  182.     //
  183.     inline void unlock();
  184.     virtual void print(ostream& = cout);
  185. };
  186.      
  187. #endif i386
  188.